package com.aplink.generic.pojo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Locale;

public class GenericObject implements Serializable {

    private static final long serialVersionUID = - 6912495916046377790L;

    private ArrayList<GenericAttribute<?, ?>> attributeList;
    private String objectMappingName;

    public GenericObject() {
        this.attributeList = new ArrayList<GenericAttribute<?, ?>>();
    }

    public boolean addAttributesFromAnotherGenericObject(
            GenericObject newGenericObject ) {
        final boolean isSuccessful = false;

        if ( newGenericObject == null ) {
            return false;
        }

        final ArrayList<GenericAttribute<?, ?>> newAttributeList = newGenericObject
                .getAttributeList();

        for ( int i = 0 ; i < newGenericObject.getAttributeList().size() ; i++ ) {

            final GenericAttribute<?, ?> attribute = newAttributeList.get( i );
            final boolean isInside = this.isContainAttribute( attribute );
            if ( isInside == false ) {
                this.attributeList.add( attribute );
            }
        }
        return isSuccessful;
    }

    public boolean checkContentInsideObject( String lowerCase ) {

        for ( int i = 0 ; i < this.attributeList.size() ; i++ ) {
            @SuppressWarnings("rawtypes")
            final GenericAttribute checkedAttribute = this.attributeList.get( i );
            if ( checkedAttribute.getValue() != null ) {
                final String value = checkedAttribute.getValue().toString()
                        .toLowerCase( Locale.getDefault() );
                if ( value.contains( lowerCase ) == true ) {
                    return true;
                }
            }
        }

        return false;
    }

    public boolean checkContentInsideObjectByAttributes( String lowerCase,
                                                         ArrayList<String> searchFields ) {

        if ( searchFields.size() == 0 ) {
            return this.checkContentInsideObject( lowerCase );
        }

        for ( int i = 0 ; i < searchFields.size() ; i++ ) {
            @SuppressWarnings("rawtypes")
            final GenericAttribute checkedAttribute = this
                    .getGenericAttributeFromObjectMappingName( searchFields
                            .get( i ) );
            if ( checkedAttribute != null ) {
                if ( checkedAttribute.getValue() != null ) {
                    final String value = checkedAttribute.getValue().toString()
                            .toLowerCase( Locale.getDefault() );
                    if ( value.contains( lowerCase ) == true ) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    public ArrayList<GenericAttribute<?, ?>> getAttributeList() {
        return this.attributeList;
    }

    public String getContentFromAttributeName( String mappingName ) {
        for ( int i = 0 ; i < this.attributeList.size() ; i++ ) {
            final GenericAttribute<?, ?> genericAtt = this.attributeList.get( i );
            if ( genericAtt.getName().toString().compareTo( mappingName ) == 0 ) {
                return String.valueOf( genericAtt.getValue() );
            }
        }
        return null;
    }

    public Object getValueFromAttributeName( String mappingName ) {
        for ( int i = 0 ; i < this.attributeList.size() ; i++ ) {
            final GenericAttribute<?, ?> genericAtt = this.attributeList.get( i );
            if ( genericAtt.getName().toString().equalsIgnoreCase( mappingName ) ) {
                return genericAtt.getValue();
            }
        }
        return null;
    }

    public void setContentByAttributeName( String mappingName, Object value ) {
        for ( int i = 0 ; i < this.attributeList.size() ; i++ ) {
            final GenericAttribute<?, ?> genericAtt = this.attributeList.get( i );
            if ( genericAtt.getName().toString().equalsIgnoreCase( mappingName ) ) {
                genericAtt.setValue( value );
                break;
            }
        }
    }

    public GenericAttribute<?, ?> getGenericAttributeFromObjectMappingName(
            String attributeName ) {
        for ( int i = 0 ; i < this.attributeList.size() ; i++ ) {
            final GenericAttribute<?, ?> genericAtt = this.attributeList.get( i );
            if ( genericAtt.getName().toString().compareTo( attributeName ) == 0 ) {
                return genericAtt;
            }
        }
        return null;
    }

    public String getObjectMappingName() {
        return this.objectMappingName;
    }

    @SuppressWarnings("rawtypes")
    public boolean isContainAnotherGenericObject( GenericObject coreGenericObject ) {

        if ( this.attributeList.size() == 0 ) {
            return false;
        }

        int count = 0;

        for ( int i = 0 ; i < coreGenericObject.getAttributeList().size() ; i++ ) {
            final GenericAttribute checkedAttribute = coreGenericObject
                    .getAttributeList().get( i );
            // if the same attribute name we will not store
            if ( this.isContainAttributeWithItsValue( checkedAttribute ) == true ) {
                count++;
            }
        }

        if ( count == coreGenericObject.getAttributeList().size() ) {
            return true;
        }

        return false;
    }

    @SuppressWarnings("rawtypes")
    public boolean isContainAttribute( GenericAttribute attribute ) {
        final boolean isInside = false;

        for ( int i = 0 ; i < this.attributeList.size() ; i++ ) {
            final GenericAttribute checkedAttribute = this.attributeList.get( i );
            // if the same attributename we will not store
            if ( checkedAttribute.getName().toString()
                    .compareToIgnoreCase( attribute.getName().toString() ) == 0 ) {
                return true;
            }
        }
        return isInside;
    }

    @SuppressWarnings("rawtypes")
    public boolean isContainAttributeWithItsValue( GenericAttribute attribute ) {
        final boolean isInside = false;

        for ( int i = 0 ; i < this.attributeList.size() ; i++ ) {
            final GenericAttribute checkedAttribute = this.attributeList.get( i );
            // if the same attributename we will not store
            if ( checkedAttribute.getName().toString()
                    .compareToIgnoreCase( attribute.getName().toString() ) == 0 ) {
                if ( checkedAttribute.getValue().toString()
                        .compareToIgnoreCase( attribute.getValue().toString() ) == 0 ) {
                    return true;

                }
            }
        }
        return isInside;
    }

    public void setAttributeList(
            ArrayList<GenericAttribute<?, ?>> _attributeList ) {
        this.attributeList = _attributeList;
    }

    public void setObjectMappingName( String _name ) {
        this.objectMappingName = _name;
    }

    public ArrayList<GenericAttribute<?, ?>> getKeyAttribute(
            ArrayList<ObjPropInfo> objPropInfos ) {
        ArrayList<GenericAttribute<?, ?>> genericAttributes = new ArrayList<GenericAttribute<?, ?>>();
        for ( ObjPropInfo info : objPropInfos ) {
            if ( info.isKey() ) {
                genericAttributes
                        .add( getGenericAttributeFromObjectMappingName( info
                                .getObjectProperty() ) );
            }
        }
        return genericAttributes;
    }

}
